<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>响应式绑定</title>
</head>

<body>
  <div id="app">
    <input type="text" v-model="text">
    <h3 v-model="text"></h3>
    {{ text }}
  </div>
  <script>
    function defineReactive(obj, key, val) {
      Object.defineProperty(obj, key, {
        get: function () {
          return val;
        },
        set: function(newVal){  // 只要data中的属性的值发生变化，就会触发set
          if(val === newVal) return
          val = newVal;
          console.log(val);
        }
      })
    }


    function observe(obj, vm) {
      Object.keys(obj).forEach(function (key) {
        // key 为data对象中的属性名 obj[key]为属性对应的值
        defineReactive(vm, key, obj[key]);
      })
    }

    // console.log(dom);
    // document.getElementById("app").appendChild(dom);

    function compile(node, vm) {
      var reg = /\{\{(.*)\}\}/;
      if (node.nodeType === 1) {// 结点类型为元素
        var attr = node.attributes;
        for (var i = 0; i < attr.length; i++) {
          if (attr[i].nodeName == "v-model") {
            var name = attr[i].nodeValue;// 获取v-mode的属性名
            node.addEventListener("input", function(e){
              vm[name] = e.target.value;
            })
            node.value = vm[name];
            node.removeAttribute("v-model");
          }
        }
      }

      if (node.nodeType === 3) {// 结点类型为文本
        if (reg.test(node.nodeValue)) {
          var name = RegExp.$1;// 获取匹配到的{{}}中的字符串
          name = name.trim();
          node.nodeValue = vm[name];
        }
      }
    }

    function nodeToFragment(node, vm) {
      var flag = document.createDocumentFragment();
      var child;
      while (child = node.firstChild) {
        console.log(child);
        compile(child, vm)
        flag.appendChild(child);
      }
      return flag;
    }
    function Vue(options) {
      this.data = options.data;
      var data = this.data;

      observe(data, this);


      var id = options.el;
      var dom = nodeToFragment(document.getElementById(id), this);
      document.getElementById("app").appendChild(dom);
    }
    var vm = new Vue({
      el: "app",
      data: {
        text: "Hello wor"
      }
    })

    // document.addEventListener()


  </script>
</body>

</html>